package cn.itcast.controller.shiro;

import cn.itcast.domain.system.Module;
import cn.itcast.domain.system.User;
import cn.itcast.service.system.ModuleService;
import cn.itcast.service.system.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * 自定义的realm
 * 1） 作用：访问数据库
 * 2） 要继承AuthorizingRealm, 实现认证与授权的方法
 */
public class AuthRealm extends AuthorizingRealm{

    // 注入service
    @Autowired
    private UserService userService;
    @Autowired
    private ModuleService moduleService;

    /**
     * 认证方法
     * 认证失败的2个异常:
     *      账号错: UnknownAccountException
     *      密码错: IncorrectCredentialsException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //1. 转换
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        //2. 获取登陆用户名称(邮箱)
        String email = (String) upToken.getPrincipal();
        //3. 调用service,查询
        User user = userService.findByEmail(email);
        //4. 判断
        if (user == null){
            // 用户名错误. 返回NULL就是用户名错误
            // 异常: UnknownAccountException 账号错误
            return null;
        }
        //5. 返回
        // 参数1: 身份对象.  subject.getPrincipal()获取的就是这里的参数1
        // 参数2: 数据库正确的密码
        // 参数3: realm名称,可以随意定义,this.getName()获取shiro提供的默认名称
        SimpleAuthenticationInfo sai =
                new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());
        return sai;
    }

    // 授权方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        /*需求:查询用户有哪些权限*/

        //1. 获取认证后的用户身份对象
        User user = (User) principals.getPrimaryPrincipal();

        //2. 根据用户查询权限
        List<Module> moduleList = moduleService.findModulesByUserId(user.getId());

        //3. 返回用户的权限
        SimpleAuthorizationInfo sai = new SimpleAuthorizationInfo();
        //3.1 判断用户的权限集合是否为空
        if (moduleList != null && moduleList.size()>0) {
            for (Module module : moduleList) {
                //3.2 添加用户拥有的权限
                sai.addStringPermission(module.getName());
            }
        }
        return sai;
    }

}
